﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

using BankService.ServiceInterface;
using BankService.CallbackInterface;

namespace BankService {
    
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class BankService : IBankService {

        private List<Client> clients;

        public BankService() {
            this.clients = new List<Client>();

            this.clients.Add(new Client("alex1", "address1", "1"));
            this.clients.Add(new Client("alex2", "address2", "2"));
        }

        public LogInOutput LogIn(LogInInput logInInput) {
            foreach(Client c in this.clients)
                if (c.Username == logInInput.Username && c.Password == logInInput.Password) {
                    c.CurrentSessionId = Guid.NewGuid().ToString();
                    c.Callback = OperationContext.Current.GetCallbackChannel<IBankCallback>();

                    LogInOutput output = new LogInOutput();
                    output.SessionId = c.CurrentSessionId;
                    output.Username = c.Username;
                    output.Address = c.Address;
                    output.AccountNumber = c.AccountNumber;
                    output.Balance = c.Balance;
                    output.Messages = c.Messages;
                    return output;
                }
            return null;
        }

        public void LogOut(string sessionId) {
            foreach (Client c in this.clients)
                if (c.CurrentSessionId == sessionId) {
                    c.CurrentSessionId = null;
                    c.CurrentSessionId = null;
                    c.Callback = null;
                    break;
                }
        }

        public bool Register(RegisterInput input) {
            foreach (Client c in this.clients)
                if (c.Username == input.Username)
                    return false;
            this.clients.Add(new Client(input.Username, input.Address, input.Password));
            return true;
        }

        public bool Transfer(TransferInput input) {
            Client sender = null;

            foreach(Client c in this.clients)
                if (c.CurrentSessionId == input.SessionId) {
                    sender = c;
                    break;
                }
            
            if (sender != null) {
                foreach (Client c in this.clients)
                    if (c.AccountNumber == input.To) {
                        sender.Balance -= input.Amount;
                        sender.Messages.Add(DateTime.UtcNow + " - You have sent " + input.Amount + " to account number " + c.AccountNumber + ".");
                        c.Balance += input.Amount;
                        string message = DateTime.UtcNow + " - You have received " + input.Amount + " from " + sender.Username + ".";
                        c.Messages.Add(message);
                        if (c.CurrentSessionId != null)
                            c.Callback.OnNewTransfer(new Transfer(input.Amount, message));
                        return true;
                    }
                return false;
            } else
                return false;
        }
    }
}
